package com.ybear.ybcomponent

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.RectF
import android.util.TypedValue
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.widget.PopupWindow
import androidx.appcompat.app.AppCompatActivity
import com.ybear.ybcomponent.base.adapter.BaseRecyclerViewAdapter
import java.util.Collections

/**
 * 工具类
 */
class Utils {
    companion object {
        // 用于判断触摸点是否在 View 范围内的辅助变量
        private val pointInViewRectF = RectF()
        private val pointInViewIntArray = IntArray( 2 )

        @JvmStatic
        fun moveRecyclerViewItem(adapter: BaseRecyclerViewAdapter<*, *>, from: Int, to: Int) {
            val list: List<*> = adapter.dataList
            if (from < 0 || from >= list.size || to < 0 || to >= list.size) return

            //数据排序
            if (from < to) {
                for (i in from until to) Collections.swap(list, i, i + 1)
            } else {
                for (i in from downTo to + 1) Collections.swap(list, i, i - 1)
            }
            //更新排序
            adapter.notifyItemMoved(from, to)
        }

        @JvmStatic
        fun getActionBarHeight(context: Context) : Int {
            // 优先使用 AppCompatActivity 的 supportActionBar
            if ( context is AppCompatActivity) return context.supportActionBar?.height ?: 0
            // 如果不是 AppCompatActivity，尝试通过主题属性获取 ActionBar 高度
            val typeVal = TypedValue()
            val attr = android.R.attr.actionBarSize
            if( !context.theme.resolveAttribute( attr, typeVal, true ) ) return 0
            return TypedValue.complexToDimensionPixelSize(
                typeVal.data, context.resources.displayMetrics
            )
        }

        /**
         * px转dp
         * @param context       上下文
         * @param px            像素值
         * @return              返回的dp值
         */
        @JvmStatic
        fun px2Dp(context: Context?, px: Float): Float {
            return if (context == null) px else px / context.resources.displayMetrics.density + 0.5f
        }

        fun px2Dp(context: Context?, px: Int): Int {
            return px2Dp(context, px.toFloat()).toInt()
        }

        /**
         * dp转px
         * @param context       上下文
         * @param dp            dip值
         * @return              返回的px值
         */
        fun dp2Px(context: Context?, dp: Float): Float {
            return if (context == null) dp else dp * context.resources.displayMetrics.density + 0.5f
        }

        @JvmStatic
        fun dp2Px(context: Context?, dp: Int): Int {
            return dp2Px(context, dp.toFloat()).toInt()
        }

        /**
         * 点击的缩放效果
         */
        @JvmStatic
        @JvmOverloads
        fun onTouchScaleAnimation(v: View?, ev: MotionEvent?, downScaleValue: Float = 0.98F) {
            if ( v == null || ev == null ) return
            when ( ev.action ) {
                MotionEvent.ACTION_DOWN -> {
                    v.scaleX = downScaleValue
                    v.scaleY = downScaleValue
                }
                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                    v.scaleX = 1f
                    v.scaleY = 1f
                }
            }
        }

        /**
         * 优化版Touch
         * @param view      优化的控件
         * @param l         监听器
         */
        @JvmStatic
        fun setOnSuperTouchListener(view: View, l: OnTouchListener?) {
            view.setTag(R.id.touch_down_time, -1L)
            view.setOnTouchListener { v: View, event: MotionEvent ->
                val ret = l != null && l.onTouch(v, event)
                var downTime = view.getTag( R.id.touch_down_time ) as Long
                when ( event.action ) {
                    MotionEvent.ACTION_DOWN -> downTime = System.currentTimeMillis()
                    MotionEvent.ACTION_UP -> {
                        if( ret ) {
                            val upTime = System.currentTimeMillis()
                            //不是长按时才触发优化，防止长按后抬起时触发一次点击事件
                            if (upTime - downTime < ViewConfiguration.getLongPressTimeout()) {
                                v.performClick()
                            }
                            downTime = -1
                        }
                    }
                }
                view.setTag( R.id.touch_down_time, downTime )
                ret
            }
        }

        /**
         * 创建一个Popup弹窗
         * @param v     需要弹窗的布局
         * @return      Popup
         */
        fun createPopupWindow(v: View): PopupWindow {
            val pw = PopupWindow(v)
            var w: Int
            var h = 0
            pw.isOutsideTouchable = true
            if (v.width.also { w = it } == 0 || v.height.also { h = it } == 0) {
                v.measure(0, 0)
                w = v.measuredWidth
                h = v.measuredHeight
            }
            pw.width = w
            pw.height = h
            return pw
        }

        @JvmOverloads
        @JvmStatic
        fun View.drawToBitmap(config: Bitmap.Config = Bitmap.Config.ARGB_8888): Bitmap? {
            var w = width
            var h = height
            if ( !isLaidOut || width <= 0 || height <= 0  ) {
                measure( 0, 0 )
                layout( 0, 0, measuredWidth, measuredHeight )
                w = measuredWidth
                h = measuredHeight
            }
            if( w <= 0 || h <= 0 ) return null
            val bmp = Bitmap.createBitmap( w, h, config )
            val canvas = Canvas( bmp )
            canvas.translate( -scaleX, -scaleY )
            draw( canvas )
            return bmp
        }

        /**
         * 判断触摸点是否在 View 范围内
         * @param view 要判断的 View
         * @param rawX 触摸 X 事件
         * @param rawY 触摸 Y 事件
         * @return 是否在 View 范围内
         */
        @JvmStatic
        fun isPointInView(view: View, rawX: Float, rawY: Float): Boolean {
            // 获取 View 在屏幕中的位置
            view.getLocationOnScreen(pointInViewIntArray)
            val viewX = pointInViewIntArray[0]
            val viewY = pointInViewIntArray[1]
            // 更新 RectF 对象，用于存储 View 在屏幕中的区域
            pointInViewRectF.set(
                viewX.toFloat(),
                viewY.toFloat(),
                (viewX + view.width).toFloat(),
                (viewY + view.height).toFloat()
            )
            // 判断触摸事件的坐标是否在 View 的区域内
            return pointInViewRectF.contains( rawX, rawY )
        }

        /**
         * 判断触摸点是否在 View 范围内
         * @param view 要判断的 View
         * @param event 触摸事件
         * @return 是否在 View 范围内
         */
        @JvmStatic
        fun isPointInView(view: View, event: MotionEvent): Boolean {
            return isPointInView( view, event.rawX, event.rawY,  )
        }
    }
}
